﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Rage.UI
{
    public partial class ItemTooltip : UserControl
    {
        /// <summary>This is used by the Non-Item charts</summary>
        public string CurrentString
        {
            get { return currentString; }
            set
            {
                itemInstance = null;
                item = null;
                //itemSet = null;
                characterItems = null;
                currentString = value;
                UpdateTooltip();
            }
        }
        private string currentString;

        private ItemInstance itemInstance; 
        public ItemInstance ItemInstance {
            get { return itemInstance; }
            set
            {
                itemInstance = value;
                item = null;
                itemSet = null;
                characterItems = null;
                currentString = null;
                UpdateTooltip();
            }
        }

        private Item item;
        public Item Item
        {
            get { return item; }
            set
            {
                itemInstance = null;
                item = value;
                itemSet = null;
                characterItems = null;
                currentString = null;
                UpdateTooltip();
            }
        }

        /// <summary>This is used by the Build Upgrade List chart</summary>
        public ItemInstance[] CharacterItems
        {
            get { return characterItems; }
            set
            {
                characterItems = value;
                itemSet = null;
                UpdateTooltip();
            }
        }
        private ItemInstance[] characterItems;

        /// <summary>This is used by the Item Sets chart</summary>
        public ItemSet ItemSet {
            get { return itemSet; }
            set {
                itemSet = value;
                item = null;
                itemInstance = null;
                characterItems = null;
                //UpdateTooltip();
            }
        }
        private ItemSet itemSet = null;

        public static Color ColorForMod(ItemSlot modType)
        {
            switch (modType)
            {
                case ItemSlot.Armoring: return Colors.Red;
                case ItemSlot.Barrel: return Colors.Red;
                case ItemSlot.Hilt: return Colors.Red;
                case ItemSlot.Mod: return Colors.Yellow;
                case ItemSlot.Enhancement: return Colors.Green;
                case ItemSlot.ColorCrystal: return Colors.Blue;
                case ItemSlot.Augment: return Colors.Purple;
                default:
                    return Colors.Transparent;
            }
        }

        private static Color ColorForQuality(ItemQuality quality)
        {
            switch (quality)
            {
                case ItemQuality.Artifact:
                    return Color.FromRgb(180, 0, 240);
                case ItemQuality.Legendary:
                    return Colors.DarkBlue;
                case ItemQuality.Prototype:
                    return Colors.Blue;
                case ItemQuality.Premium:
                    return Colors.Green;
                case ItemQuality.Standard:
                    return Colors.White;
                case ItemQuality.Cheap:
                    return Colors.Gray;
                case ItemQuality.Temp:
                default:
                    return Colors.White;
            }
        }

        private void NonItemTooltip() {
            RootLayout.Visibility = Visibility.Visible;
            try {
                string Title = CurrentString.Split('|')[0].Trim();
                string Desc = CurrentString.Split('|')[1].Trim();

                ItemName.Text = Title;
                ItemName.Foreground = new SolidColorBrush(Color.FromRgb(180, 0, 240));

                // Hide Item related fields
                TypesPanel.Visibility =
                ItemArmorAndRating.Visibility =
                ItemShieldAbsorb.Visibility =
                ItemShieldChance.Visibility =
                StatPanel.Visibility =
                UnusedStatPanel.Visibility =
                ItemModifications.Visibility =
                ModNamesLabel1.Visibility = ModColor1.Visibility = ModStat1.Visibility =
                ModNamesLabel2.Visibility = ModColor2.Visibility = ModStat2.Visibility =
                ModNamesLabel3.Visibility = ModColor3.Visibility = ModStat3.Visibility =
                ModNamesLabel4.Visibility = ModColor4.Visibility = ModStat4.Visibility =
                ModNamesLabel5.Visibility = ModColor5.Visibility = ModStat5.Visibility =
                SetLabel.Visibility = Visibility.Collapsed;

                // Show Location Label because we are using it for the Statement
                LocationLabel.Visibility = Visibility.Visible;
                LocationLabel.Text = Desc;

                if (ItemSet != null && ItemSet.Count > 0) {
                    ItemsGrid.Visibility = Visibility.Visible;
                    #region Additional Items, like in Build Upgrade List
                    ItemsGrid.Children.Clear();
                    ItemsGrid.RowDefinitions.Clear();
                    int row = 0;
                    foreach (ItemInstance setItem in ItemSet)
                    {
                        ItemsGrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });
                        if (setItem == null) continue;

                        Image iconImage = new Image();
                        iconImage.Style = Resources["SmallIconStyle"] as Style;
                        iconImage.Source = Icons.AnIcon(setItem.Item.IconPath);
                        Grid.SetColumn(iconImage, 0);
                        Grid.SetRow(iconImage, row);
                        ItemsGrid.Children.Add(iconImage);

                        if (setItem.ItemMod1Id != "0")
                        {
                            Image mod1Image = new Image();
                            mod1Image.Style = Resources["SmallIconStyle"] as Style;
                            mod1Image.Source = Icons.AnIcon(setItem.ItemMod1.IconPath);
                            Grid.SetColumn(mod1Image, 1);
                            Grid.SetRow(mod1Image, row);
                            ItemsGrid.Children.Add(mod1Image);
                        }

                        if (setItem.ItemMod2Id != "0")
                        {
                            Image mod2Image = new Image();
                            mod2Image.Style = Resources["SmallIconStyle"] as Style;
                            mod2Image.Source = Icons.AnIcon(setItem.ItemMod2.IconPath);
                            Grid.SetColumn(mod2Image, 2);
                            Grid.SetRow(mod2Image, row);
                            ItemsGrid.Children.Add(mod2Image);
                        }

                        if (setItem.ItemMod3Id != "0")
                        {
                            Image mod3Image = new Image();
                            mod3Image.Style = Resources["SmallIconStyle"] as Style;
                            mod3Image.Source = Icons.AnIcon(setItem.ItemMod3.IconPath);
                            Grid.SetColumn(mod3Image, 3);
                            Grid.SetRow(mod3Image, row);
                            ItemsGrid.Children.Add(mod3Image);
                        }

                        if (setItem.ItemMod4Id != "0")
                        {
                            Image mod4Image = new Image();
                            mod4Image.Style = Resources["SmallIconStyle"] as Style;
                            mod4Image.Source = Icons.AnIcon(setItem.ItemMod4.IconPath);
                            Grid.SetColumn(mod4Image, 4);
                            Grid.SetRow(mod4Image, row);
                            ItemsGrid.Children.Add(mod4Image);
                        }

                        if (setItem.ItemMod3Id != "0")
                        {
                            Image mod5Image = new Image();
                            mod5Image.Style = Resources["SmallIconStyle"] as Style;
                            mod5Image.Source = Icons.AnIcon(setItem.ItemMod5.IconPath);
                            Grid.SetColumn(mod5Image, 5);
                            Grid.SetRow(mod5Image, row);
                            ItemsGrid.Children.Add(mod5Image);
                        }

                        TextBlock nameText = new TextBlock();
                        nameText.Text = string.Format("{0}", setItem.Item.Name);
                        nameText.Foreground = new SolidColorBrush(ColorForQuality(setItem.Item.Quality));
                        Grid.SetColumn(nameText, 4);
                        Grid.SetRow(nameText, row);
                        ItemsGrid.Children.Add(nameText);

                        row++;
                    }
                    #endregion
                } else {
                    ItemsGrid.Visibility = Visibility.Collapsed;
                }
            } catch (Exception ex) {
                new Base.ErrorBox() {
                    Title = "Error setting up a Non-Item Tooltip",
                    Function = "NonItemTooltip()",
                    TheException = ex,
                }.Show();
            }
        }

        public static void List2Panel(WrapPanel p, IList<string> li, Brush fore, bool allowWrap)
        {
            // reset
            p.Children.Clear();

            // show
            p.Visibility = li.Count > 0 ? Visibility.Visible : Visibility.Collapsed;

            // fill
            foreach (var s in li)
            {
                var c = new TextBlock {
                    Margin = new Thickness(0, 0, 8, 0),
                    HorizontalAlignment = HorizontalAlignment.Left,
                    VerticalAlignment = VerticalAlignment.Top,
                    Text = s,
                    TextWrapping = allowWrap ? TextWrapping.Wrap : TextWrapping.NoWrap,
                    Style = (new ItemTooltip()).Resources["NormalTextStyle"] as Style,
                    Foreground = new SolidColorBrush(Colors.AliceBlue),
                };

                if (fore != null)
                    c.Foreground = fore;
                p.Children.Add(c);
            }
        }

        public static List<string> StatListToSortedStatList(List<string> source)
        {
            List<string> retVal = new List<string>();
            List<string> retVal2 = new List<string>();
            List<string> retVal3 = new List<string>();
            List<string> retVal4 = new List<string>();
            //
            while(source.Count > 0)
            {
                for (int i = 0; i < source.Count; )
                {
                    if (!source[i].Contains("%")
                        && (source[i].EndsWith(" Strength")
                            || source[i].EndsWith(" Aim")
                            || source[i].EndsWith(" Cunning")
                            || source[i].EndsWith(" Willpower")
                            || source[i].EndsWith(" Presence")))
                    {
                        retVal.Add(source[i]);
                        source.RemoveAt(i);
                    }
                    else if (!source[i].Contains("%") && (source[i].EndsWith(" Endurance")))
                    {
                        retVal2.Add(source[i]);
                        source.RemoveAt(i);
                    }
                    else if (!source[i].Contains("%") && (source[i].Contains("Force") || source[i].Contains("Tech")))
                    {
                        retVal3.Add(source[i]);
                        source.RemoveAt(i);
                    }
                    else
                    {
                        retVal4.Add(source[i]);
                        source.RemoveAt(i);
                    }
                }
            }
            //
            retVal.AddRange(retVal2);
            retVal.AddRange(retVal3);
            retVal.AddRange(retVal4);
            //
            return source = retVal;
        }

        public static List<ItemSlot> EquippableSlots = new List<ItemSlot> { ItemSlot.Armoring, ItemSlot.Barrel, ItemSlot.Hilt, ItemSlot.Mod, ItemSlot.Enhancement, ItemSlot.ColorCrystal, ItemSlot.Augment, };
        private bool ModUISetup(Item actualItem, Item itemMod, ItemSlot modType, Border modColor, Image modImage, TextBlock modNamesLabel, StackPanel modStat)
        {
            bool hasMods = false;
            modImage.Source = null; modStat.Children.Clear();
            if (actualItem == null || modType == ItemSlot.None) {
                modColor.Visibility = modImage.Visibility = modStat.Visibility = modNamesLabel.Visibility = Visibility.Collapsed;
                modNamesLabel.Text = "";
            } else {
                modColor.Visibility = modImage.Visibility = modStat.Visibility = modNamesLabel.Visibility = Visibility.Visible;
                modNamesLabel.Text = modType.ToString();
                modColor.Background = new SolidColorBrush(ColorForMod(modType));
                hasMods |= true;
            }
            if (itemMod != null) {
                if (EquippableSlots.Contains(modType)) {
                    modColor.Visibility = Visibility.Visible;
                    modColor.Background = new SolidColorBrush(ColorForMod(modType));
                    modImage.Visibility = Visibility.Visible;
                    modImage.Source = null;
                    modStat.Visibility = Visibility.Visible;
                    modStat.Children.Clear();
                    hasMods |= true;
                }
                modImage.Source = Icons.AnIcon(itemMod.IconPath);
                foreach (string s in Calculations.GetRelevantStats(itemMod.Stats).ToString().Split(','))
                {
                    if (s.EndsWith(" Armor")) { continue; }
                    string value = s.Contains("Armor Penetration") ? s.Replace("Armor Penetration", "ArP") : s;
                    TextBlock t = new TextBlock() {
                        Style = this.Resources["NormalTextStyle"] as Style,
                        Margin = new Thickness(2, 0, 2, 0),
                    };
                    t.Text = "+" + value.Trim();
                    modStat.Children.Add(t);
                }
                modNamesLabel.Text += ": " + itemMod.Name + " (" + itemMod.ItemLevel + ")";
                return hasMods;
            } else { modNamesLabel.Text += ": Empty"; hasMods |= false; }
            //
            return hasMods;
        }

        public void UpdateTooltip()
        {
            Item actualItem = null;
            if (ItemInstance != null) {
                actualItem = ItemInstance.Item;
            } else if (Item != null) {
                actualItem = Item;
            } else if (ItemSet != null) {
                NonItemTooltip();
                return;
            } else if (CurrentString != null && CurrentString != "") {
                NonItemTooltip();
                return;
            } else {
                RootLayout.Visibility = Visibility.Collapsed;
                return;
            }
            RootLayout.Visibility = Visibility.Visible;

            ItemName.Text = ItemInstance != null ? ItemInstance.Name : (actualItem != null ? actualItem.Name : "");
            ItemName.Foreground = new SolidColorBrush(ColorForQuality(actualItem != null ? actualItem.Quality : ItemQuality.Standard));

            #region Displaying Item Types
            var liTypes = new List<string>();

            if (actualItem != null && (actualItem.Type != ItemType.None
                                       || (actualItem.Type == ItemType.None
                                           && (actualItem.Slot == ItemSlot.Implant
                                               || actualItem.Slot == ItemSlot.Relic
                                               || actualItem.Slot == ItemSlot.Armoring
                                               || actualItem.Slot == ItemSlot.Barrel
                                               || actualItem.Slot == ItemSlot.Hilt
                                               || actualItem.Slot == ItemSlot.Mod
                                               || actualItem.Slot == ItemSlot.Enhancement
                                               || actualItem.Slot == ItemSlot.ColorCrystal
                                               || actualItem.Slot == ItemSlot.Augment
                ))))
            {
                liTypes.Add(string.Format("[{0}]", actualItem.Id));

                if (actualItem.ItemLevel > 0)
                    liTypes.Add(string.Format("[{0}]", actualItem.ItemLevel));

                if (actualItem.Bind != BindsOn.None)
                    liTypes.Add(string.Format("[{0}]", actualItem.Bind));

                if (!string.IsNullOrEmpty(actualItem.SlotString) && actualItem.Type != ItemType.None) {
                    liTypes.Add(string.Format("[{0} ({1})]", actualItem.SlotString, actualItem.Type));
                } else {
                    if (!string.IsNullOrEmpty(actualItem.SlotString))
                    {
                        liTypes.Add(string.Format("[{0}]", actualItem.SlotString));
                    }
                    if (actualItem.Type != ItemType.None)
                    {
                        liTypes.Add(string.Format("[{0}]", actualItem.Type));
                    }
                }
            }
            List2Panel(TypesPanel, liTypes, new SolidColorBrush(Color.FromRgb(57, 195, 226)), false);
            
            #endregion // Displaying Item Types

            #region Displaying Item Stats
            List<string> statsList = new List<string>();
            List<string> unusedStatsList = new List<string>();
            if (Rage.Properties.GeneralSettings.Default.DisplayUnusedStats) {
                //statsList.Add("Used Stats:");
                unusedStatsList.Add("Unused Stats:");
            }

            ItemArmorAndRating.Visibility = ItemShieldAbsorb.Visibility = ItemShieldChance.Visibility = Visibility.Collapsed;
            ItemArmorAndRating.Text = ItemShieldAbsorb.Text = ItemShieldChance.Text = "";
            if (actualItem != null) {
                if (actualItem.Type == ItemType.AssaultCannon
                    || actualItem.Type == ItemType.BlasterPistol
                    || actualItem.Type == ItemType.BlasterRifle
                    || actualItem.Type == ItemType.DoubleBladedLightsaber
                    || actualItem.Type == ItemType.Electrostaff
                    || actualItem.Type == ItemType.Lightsaber
                    || actualItem.Type == ItemType.Shotgun
                    || actualItem.Type == ItemType.SniperRifle
                    || actualItem.Type == ItemType.Techblade
                    || actualItem.Type == ItemType.TechStaff
                    || actualItem.Type == ItemType.Vibroknife
                    || actualItem.Type == ItemType.Vibrosword
                    )
                {
                    ItemArmorAndRating.Visibility = Visibility.Visible;
                    ItemArmorAndRating.Text = string.Format("{0:#,##0.0}-{1:#,##0.0} {2} Damage (Rating {3:#,##0})",
                        actualItem.MinDamage, actualItem.MaxDamage, actualItem.DamageType, actualItem.Rating);
                }
                // Pull the Actual Stats, including Random Suffix if it has one
                Stats stats = ItemInstance != null ? ItemInstance.GetTotalStats() : actualItem.Stats;
                // Relevant Stats
                Stats relevantStats = Calculations.GetRelevantStats(stats);
                var nonzeroStats = relevantStats.Values(x => x != 0);
                foreach (System.Reflection.PropertyInfo info in nonzeroStats.Keys) {
                    float value = nonzeroStats[info];
                    if (Stats.IsPercentage(info)) value *= 100;
                    value = (float)Math.Round(value * 100f) / 100f;
                    if (Extensions.DisplayName(info) == " Armor" || Extensions.DisplayName(info) == "Armor Rating") {
                        ItemArmorAndRating.Visibility = Visibility.Visible;
                        ItemArmorAndRating.Text = string.Format("{0:#,##0} Armor (Rating {1:#,##0})",
                            actualItem.Stats.Armor, actualItem.Rating);
                        continue;
                    } else if (Extensions.DisplayName(info) == "% Shield Absorption") {
                        ItemShieldAbsorb.Visibility = Visibility.Visible;
                        ItemShieldAbsorb.Text = string.Format("Shield Absorb: {0:#0.0#%}", actualItem.Stats.Absorb);
                        continue;
                    } else if (Extensions.DisplayName(info) == "% Shield Chance") {
                        ItemShieldChance.Visibility = Visibility.Visible;
                        ItemShieldChance.Text = string.Format("Shield Chance: {0:#0.0#%}", actualItem.Stats.Shield);
                        continue;
                    }
                    string text = string.Format("{2}{0}{1}", value, Extensions.DisplayName(info), value >= 0 ? "+" : "-");
                    statsList.Add(text);
                }
                foreach (SpecialEffect effect in relevantStats.SpecialEffects()) {
                    string text = effect.ToString();
                    statsList.Add(text);
                }
                // Irrelevant Stats
                Stats unusedStats = stats - relevantStats;
                var unusedNonzeroStats = unusedStats.Values(x => x != 0);
                foreach (System.Reflection.PropertyInfo info in unusedNonzeroStats.Keys) {
                    float value = unusedNonzeroStats[info];
                    if (Stats.IsPercentage(info)) value *= 100;
                    value = (float)Math.Round(value * 100f) / 100f;

                    string text = string.Format("{2}{0}{1}", value, Extensions.DisplayName(info), value >= 0 ? "+" : "-");
                    unusedStatsList.Add(text);
                }
                foreach (SpecialEffect effect in unusedStats.SpecialEffects()) {
                    string text = effect.ToString();
                    unusedStatsList.Add(text);
                }
            }
            if (statsList.Count > 0 || !Rage.Properties.GeneralSettings.Default.DisplayUnusedStats)
            {
                if (unusedStatsList.Count <= 1 && Rage.Properties.GeneralSettings.Default.DisplayUnusedStats)
                {
                    // Take off the "Used Stats" statement, we don't need to differentiate
                    //statsList.RemoveAt(0);
                }
                List2Panel(StatPanel, statsList = StatListToSortedStatList(statsList), new SolidColorBrush(Color.FromRgb(232, 186, 62)), true);
            } else { StatPanel.Children.Clear(); }
            if (Rage.Properties.GeneralSettings.Default.DisplayUnusedStats && unusedStatsList.Count > 1)
            { List2Panel(UnusedStatPanel, unusedStatsList = StatListToSortedStatList(unusedStatsList), new SolidColorBrush(Colors.Gray), true); }
            else { UnusedStatPanel.Children.Clear(); }
            if (statsList.Count == 0 && unusedStatsList.Count < 2) { ItemTotalStats.Visibility = Visibility.Collapsed; } else { ItemTotalStats.Visibility = Visibility.Visible; }
            #endregion

            #region Displaying Item Sets
            if (actualItem != null && actualItem.SetName != null && actualItem.SetName != "")
            {
                SetLabel.Text = actualItem.SetName;
                SetLabel.Visibility = Visibility.Visible;
            } else {
                SetLabel.Text = "";
                SetLabel.Visibility = Visibility.Collapsed;
            }
            #endregion

            #region Setting Up Mods
            bool hasMods = false;
            hasMods |= ModUISetup(actualItem, ItemInstance == null ? null : ItemInstance.ItemMod1, actualItem == null ? ItemSlot.None : actualItem.ItemArmoringHiltBarrelType, ModColor1, ModImage1, ModNamesLabel1, ModStat1);
            hasMods |= ModUISetup(actualItem, ItemInstance == null ? null : ItemInstance.ItemMod2, actualItem == null ? ItemSlot.None : actualItem.ItemModType,                ModColor2, ModImage2, ModNamesLabel2, ModStat2);
            hasMods |= ModUISetup(actualItem, ItemInstance == null ? null : ItemInstance.ItemMod3, actualItem == null ? ItemSlot.None : actualItem.ItemEnhancementType,        ModColor3, ModImage3, ModNamesLabel3, ModStat3);
            hasMods |= ModUISetup(actualItem, ItemInstance == null ? null : ItemInstance.ItemMod4, actualItem == null ? ItemSlot.None : actualItem.ItemColorCrystalType,       ModColor4, ModImage4, ModNamesLabel4, ModStat4);
            hasMods |= ModUISetup(actualItem, ItemInstance == null ? null : ItemInstance.ItemMod5, actualItem == null ? ItemSlot.None : actualItem.ItemAugmentType,            ModColor5, ModImage5, ModNamesLabel5, ModStat5);
            ItemModifications.Visibility = hasMods ? Visibility.Visible : Visibility.Collapsed;
            #endregion

            #region Displaying Item Light/Dark Requirements
            if (actualItem != null && actualItem.RequiresLightDark != 0) {
                if (actualItem.RequiresLightDark < 0) {
                    RequiresLightDark.Text = String.Format("Requires Light {0}", Math.Abs(actualItem.RequiresLightDark));
                } else {
                    RequiresLightDark.Text = String.Format("Requires Dark {0}", Math.Abs(actualItem.RequiresLightDark));
                }
                RequiresLightDark.Visibility = Visibility.Visible;
            } else {
                RequiresLightDark.Visibility = Visibility.Collapsed;
            }
            #endregion

            #region Location Section
            // the actualItem.Id check to make sure it's an item, not a reforging or something
            if (actualItem != null && actualItem.Id != "0") {
                if (/*actualItem.LocationInfo != null &&*/
                    /*actualItem.LocationInfo.Count > 0 &&*/
                    ((LocationLabel.Text = actualItem.GetFullLocationDesc) != ""))
                {
                    LocationLabel.Visibility = Visibility.Visible;
                } else { LocationLabel.Visibility = Visibility.Collapsed; }
            } else { LocationLabel.Visibility = Visibility.Collapsed; }
            #endregion

            #region Additional Items, like in Build Upgrade List
            ItemsGrid.Children.Clear();
            ItemsGrid.RowDefinitions.Clear();
            if (CharacterItems == null || CharacterItems.Length == 0) ItemsGrid.Visibility = Visibility.Collapsed;
            else
            {
                ItemsGrid.Visibility = Visibility.Visible;
                int row = 0;
                foreach (ItemInstance characterItem in CharacterItems)
                {
                    ItemsGrid.RowDefinitions.Add(new RowDefinition() { Height = GridLength.Auto });

                    if (characterItem == null) continue;
                    Image iconImage = new Image();
                    iconImage.Style = Resources["SmallIconStyle"] as Style;
                    iconImage.Source = Icons.AnIcon(characterItem.Item.IconPath);
                    Grid.SetColumn(iconImage, 0);
                    Grid.SetRow(iconImage, row);
                    ItemsGrid.Children.Add(iconImage);

                    if (characterItem.ItemMod1Id != "0")
                    {
                        Image mod1Image = new Image();
                        mod1Image.Style = Resources["SmallIconStyle"] as Style;
                        mod1Image.Source = Icons.AnIcon(characterItem.ItemMod1.IconPath);
                        Grid.SetColumn(mod1Image, 1);
                        Grid.SetRow(mod1Image, row);
                        ItemsGrid.Children.Add(mod1Image);
                    }

                    if (characterItem.ItemMod2Id != "0")
                    {
                        Image mod2Image = new Image();
                        mod2Image.Style = Resources["SmallIconStyle"] as Style;
                        mod2Image.Source = Icons.AnIcon(characterItem.ItemMod2.IconPath);
                        Grid.SetColumn(mod2Image, 2);
                        Grid.SetRow(mod2Image, row);
                        ItemsGrid.Children.Add(mod2Image);
                    }

                    if (characterItem.ItemMod3Id != "0")
                    {
                        Image mod3Image = new Image();
                        mod3Image.Style = Resources["SmallIconStyle"] as Style;
                        mod3Image.Source = Icons.AnIcon(characterItem.ItemMod3.IconPath);
                        Grid.SetColumn(mod3Image, 3);
                        Grid.SetRow(mod3Image, row);
                        ItemsGrid.Children.Add(mod3Image);
                    }
                    if (characterItem.ItemMod4Id != "0")
                    {
                        Image mod4Image = new Image();
                        mod4Image.Style = Resources["SmallIconStyle"] as Style;
                        mod4Image.Source = Icons.AnIcon(characterItem.ItemMod3.IconPath);
                        Grid.SetColumn(mod4Image, 4);
                        Grid.SetRow(mod4Image, row);
                        ItemsGrid.Children.Add(mod4Image);
                    }
                    if (characterItem.ItemMod5Id != "0")
                    {
                        Image mod5Image = new Image();
                        mod5Image.Style = Resources["SmallIconStyle"] as Style;
                        mod5Image.Source = Icons.AnIcon(characterItem.ItemMod3.IconPath);
                        Grid.SetColumn(mod5Image, 5);
                        Grid.SetRow(mod5Image, row);
                        ItemsGrid.Children.Add(mod5Image);
                    }

                    TextBlock nameText = new TextBlock();
                    nameText.Text = string.Format("{0}", characterItem.Item.Name);
                    nameText.Foreground = new SolidColorBrush(ColorForQuality(characterItem.Item.Quality));
                    Grid.SetColumn(nameText, 4);
                    Grid.SetRow(nameText, row);
                    ItemsGrid.Children.Add(nameText);

                    row++;
                }
            }
            #endregion
        }

        public void Show(UIElement relativeTo) { Show(relativeTo, 0, 0); }
        public void Show(UIElement relativeTo, double offsetX, double offsetY)
        {
#if SILVERLIGHT
            try
            {
                GeneralTransform gt = relativeTo.TransformToVisual((UIElement)this.Parent);
                Point offset = gt.Transform(new Point(offsetX, offsetY));
                ItemPopup.VerticalOffset = offset.Y;
                ItemPopup.HorizontalOffset = offset.X;
                ItemPopup.IsOpen = true;

                ItemGrid.Measure(App.Current.RootVisual.DesiredSize);

                GeneralTransform transform = relativeTo.TransformToVisual(App.Current.RootVisual);
                // Lets make sure that we don't clip from the bottom
                double distBetweenBottomOfPopupAndBottomOfWindow =
                    App.Current.RootVisual.RenderSize.Height - offsetY -
                    transform.Transform(new Point(0, ItemGrid.DesiredSize.Height)).Y;
                if (distBetweenBottomOfPopupAndBottomOfWindow < 0)
                {
                    ItemPopup.VerticalOffset += distBetweenBottomOfPopupAndBottomOfWindow;
                }
                // Lets make sure that we don't clip from the right side
                double distBetweenRightSideOfPopupAndBottomOfWindow =
                    App.Current.RootVisual.RenderSize.Width - offsetX -
                    transform.Transform(new Point(ItemGrid.DesiredSize.Width, 0)).X;
                if (distBetweenRightSideOfPopupAndBottomOfWindow < 0)
                {
                    ItemPopup.HorizontalOffset += distBetweenRightSideOfPopupAndBottomOfWindow;
                }
            }
            catch (ArgumentException)
            {
                // Value does not fall within the expected range
                // apparently happens if you call while it's still loading the visual tree or something
            }
#else
            ItemPopup.PlacementTarget = relativeTo;
            ItemPopup.PlacementRectangle = new Rect(0, offsetY, offsetX, relativeTo.RenderSize.Height);
            ItemPopup.Placement = System.Windows.Controls.Primitives.PlacementMode.Right;
            ItemPopup.IsOpen = true;
#endif
        }

        public void Hide()
        {
            ItemPopup.IsOpen = false;
        }

        public ItemTooltip()
        {
            // Required to initialize variables
            InitializeComponent();
        }
    }
}
